#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import cgi
from datetime import datetime
from datetime import timedelta

import wsgiref.handlers

from google.appengine.api import users
from google.appengine.api import images
from google.appengine.api import urlfetch

from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext import db

class WCPictureOwner(db.Model):
    user = db.UserProperty()
    joinDt = db.DateTimeProperty(auto_now_add=True)
    lastLogin = db.DateTimeProperty(auto_now_add=True)
    lat = db.FloatProperty()
    lng = db.FloatProperty()
    doing = db.StringProperty()
  
class WCPicture(db.Model):
    id = db.IntegerProperty()
    pic = db.BlobProperty()
    dt = db.DateTimeProperty(auto_now_add=True)
    owner = db.ReferenceProperty(WCPictureOwner)
    lat = db.FloatProperty()
    lng = db.FloatProperty()
    doing = db.StringProperty()


class MainHandler(webapp.RequestHandler):
    def get(self):
        current_user = users.get_current_user()
        if not current_user:
            self.redirect(users.create_login_url(self.request.path))
        else:
            owner = WCPictureOwner.gql("where user = :1", current_user).get()
            if not owner:
                owner = WCPictureOwner(user=current_user)
                owner.put()
            else:
                owner.lastLogin = datetime.now()
                owner.lat = None;
                owner.lng = None;
                owner.doing = None;
                owner.put()
            
        directory = os.path.dirname(__file__)
        path = os.path.join(directory, "WebcamCapture.html")

        self.response.out.write(template.render(path, {}))

class UploadPic(webapp.RequestHandler):
    def get(self):
        current_user = users.get_current_user()
        if not current_user:
            self.redirect(users.create_login_url(self.request.path))
        else:
            self.response.out.write(current_user.nickname() + "(" + current_user.email() + ")")
            self.response.out.write("[<a href='" + users.create_logout_url(self.request.path) + "'>logout</a>]")
            self.response.out.write("<p>")
            
            self.response.out.write("""
            [For upload testing]<br>
            <form action="uploadPic" method="POST" enctype="multipart/form-data">
            <input type="hidden" name="source" value="web">
            picture: <input type="file" name="Filedata"><br>
            <input type="submit" value="upload">
            </form><p>\n""")
            
            self.response.out.write("[Uploaded pictures]<br>\n")
            owner = WCPictureOwner.gql("where user = :1", current_user).get()
            if owner:
                owner.lastLogin = datetime.now()
                owner.put()
                
                self.response.out.write("<table border='0'>\n")
                
                #pics = owner.wcpicture_set
                pics = WCPicture.gql("where owner = :1 order by dt desc", owner)
                
                i = 0
                for pic in pics:
                    if i % 10 == 0:
                        if i != 0:
                            self.response.out.write("</tr>\n")
                        self.response.out.write("<tr valign='top'>\n")
                    
                    self.response.out.write("<td>")
                    self.response.out.write("<img title='id=" + str(pic.id)
                                            + ", " + (pic.dt + timedelta(hours=+8)).strftime("%Y-%m-%d")
                                            + " " + (pic.dt + timedelta(hours=+8)).strftime("%H:%M:%S") + " GMT+8"
                                            + ", lat=" + str(pic.lat)
                                            + ", lng=" + str(pic.lng)
                                            + "' src='getPic/" + str(pic.id) + "?w=80&h=60'>")
                    self.response.out.write("<br>" + (pic.dt + timedelta(hours=+8)).strftime("%H:%M:%S") + " GMT+8")
                    self.response.out.write("</td>\n")
                    
                    i = i + 1
                
                self.response.out.write("</tr>\n")
                self.response.out.write("</table>\n")
            else:
                self.response.out.write("we can't find this picture owner<br>\n")
                
    def post(self):
        current_user = users.get_current_user()
        if current_user:
            owner = WCPictureOwner.gql("where user = :1", current_user).get()
            if not owner:
                owner = WCPictureOwner(user=current_user)
                owner.put()
                

            #delete pics before 30 min   
            deleteResults = WCPicture.gql("where owner = :1 and dt < :2"
                                          , owner, datetime.now()-timedelta(minutes=30))
            for deleteResult in deleteResults:
                db.delete(deleteResult)
                
                                            
            pic = self.request.get("Filedata")
            if pic:
                raw_img = images.Image(pic)
                raw_img.resize(width=320, height=240)
                raw_img.im_feeling_lucky()
                
                query = WCPicture.gql("order by id desc").get()
                if query:
                    new_id = query.id + 1
                else:
                    new_id = 1
                    
                picture = WCPicture(id=new_id
                                  , pic=raw_img.execute_transforms(output_encoding=images.PNG)
                                  , owner=owner
                                  , lat=owner.lat
                                  , lng=owner.lng
                                  , doing=owner.doing)
                
                picture.put()
                
                err = ""
            else:
                err = "no_pic"
        else:
            err = "no_logon"
            
        if self.request.get("source") == "web":
            if err == "":
                self.response.out.write("Success<br><a href='javascript:history.back();'>[back]</a>")
            elif err == "no_pic":
                self.response.out.write("Error: no picture<br><a href='javascript:history.back();'>[back]</a>")
            elif err == "no_logon":
                self.response.out.write("Error: no logon<br><a href='javascript:history.back();'>[back]</a>")
        else:
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.out.write("err=" + err)

class GetPic(webapp.RequestHandler):
    def get(self, pic_id):
        pic = WCPicture.gql("where id = :1", int(pic_id)).get()
        if pic:
            w = self.request.get("w")
            h = self.request.get("h")

            raw_img = images.Image(pic.pic)
            if w<>"" and h<>"":
                raw_img.resize(width=int(w), height=int(h))
            raw_img.im_feeling_lucky()            
            
            self.response.headers['Content-Type'] = 'image/png'
            self.response.out.write(raw_img.execute_transforms(output_encoding=images.PNG))            

class UpdateLatLng(webapp.RequestHandler):
    def get(self):
        current_user = users.get_current_user()
        if current_user:
            owner = WCPictureOwner.gql("where user = :1", current_user).get()
            if not owner:
                owner = WCPictureOwner(user=current_user)
            owner.lat = float(self.request.get("lat"))
            owner.lng = float(self.request.get("lng"))
            owner.put()
            
            err = ""
        else:
            err = "no_logon"
        
        self.response.out.write("err=" + err)
        
class UpdateDoing(webapp.RequestHandler):
    def get(self):
        current_user = users.get_current_user()
        if current_user:
            owner = WCPictureOwner.gql("where user = :1", current_user).get()
            if not owner:
                owner = WCPictureOwner(user=current_user)
            owner.doing = self.request.get("doing")
            owner.put()
            
            err = ""
        else:
            err = "no_logon"
        
        self.response.out.write("err=" + err)
       
class UserList(webapp.RequestHandler):
    def get(self):   
        query = WCPictureOwner.gql("order by lastLogin desc").fetch(50)
        
        self.response.out.write("<owners>\n")
        for owner in query:
            pic = WCPicture.gql("where owner = :1 order by dt desc", owner).get()
            if pic:
                if pic.doing:
                    strDoing = cgi.escape(pic.doing)
                else:
                    strDoing = ""
                    
                self.response.out.write("<owner nick=\"" + owner.user.nickname() + "\""
                                    + " picid=\"" + str(pic.id) + "\""
                                    + " dt=\"" + str(pic.dt) + "\""
                                    + " lat=\"" + str(pic.lat) + "\""
                                    + " lng=\"" + str(pic.lng) + "\""
                                    + " doing=\"" + strDoing + "\""
                                    + " />\n")
        self.response.out.write("</owners>\n")
    
def main():
  application = webapp.WSGIApplication([('/WebcamCapture/', MainHandler)
                                        , ('/WebcamCapture/uploadPic', UploadPic)
                                        , ('/WebcamCapture/getPic/([^/]+)', GetPic)
                                        , ('/WebcamCapture/updateLatLng', UpdateLatLng)
                                        , ('/WebcamCapture/updateDoing', UpdateDoing)
                                        , ('/WebcamCapture/userList', UserList)
                                        ], debug=True)
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
  main()
